package model

import (
	"common/helper"
	"database/sql"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"github.com/valyala/fasthttp"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// BusinessLoginResp 业务员登录返回数据结构体
type BusinessLoginResp struct {
	Id           string `json:"id" cbor:"id"`                       // id
	Token        string `json:"token" cbor:"token"`                 // 用户token
	LoginAccount string `json:"login_account" cbor:"login_account"` // 登录账号
	OperatorId   string `json:"operator_id" cbor:"operator_id"`     // 渠道id
	Date         int64  `json:"date" cbor:"date"`                   //

	Seamo   string `json:"seamo" cbor:"seamo"`       //
	CodeUrl string `json:"code_url" cbor:"code_url"` //
}

func BusinessList(page, pageSize int, id, parentId, proxyType string, ctx *fasthttp.RequestCtx) (BusinessInfoData, error) {

	data := BusinessInfoData{}
	where := " 1=1"
	oderBy := "created_at"
	oderType := "desc"
	if id != "" {
		where += " and id=" + id
	}
	if parentId != "" {
		where += " and operator_name=" + parentId
	}
	if proxyType != "" {
		where += " and type='" + proxyType + "'"
	}
	order := oderBy + " " + oderType

	table := "tbl_business_info"
	join := ""
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and operator_id=" + loginUser.Operator
	} else if loginUser.Businsess != "" {
		where += " and id in(" + GetBusinessTeam(loginUser.Businsess, loginUser.Businsess) + ")"
	}

	offset := (page - 1) * pageSize
	if page >= 1 {
		count := "select count(1) from " + table + " " + join + " where " + where

		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "*"
	query := "select " + field + "  from " + table + " as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)

	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

// 预编译正则表达式提升性能
var (
	hasLower    = regexp.MustCompile(`[a-z]`)          // 包含小写字母
	hasUpper    = regexp.MustCompile(`[A-Z]`)          // 包含大写字母
	hasDigit    = regexp.MustCompile(`[0-9]`)          // 包含数字
	onlyAllowed = regexp.MustCompile(`^[A-Za-z0-9]+$`) // 仅允许字母数字（按需修改）
	//onlyAllowed = regexp.MustCompile(`^[A-Za-z0-9!@#$%^&*]+$`)   // 允许字母数字和特殊符号
)

func ValidatePassword(password string) bool {
	// 验证长度 ≥8 位
	if len(password) < 8 {
		return false
	}

	// 验证必须包含大小写字母和数字
	if !hasLower.MatchString(password) {
		return false
	}
	if !hasUpper.MatchString(password) {
		return false
	}
	if !hasDigit.MatchString(password) {
		return false
	}

	// 验证是否仅包含允许的字符
	if !onlyAllowed.MatchString(password) {
		return false
	}

	return true
}

func BusinessInsert(data TblBusinessInfo) error {
	Id := GetRandId(7)
	record := TblBusinessInfo{
		Id:           Id,
		AccountName:  data.AccountName,
		LoginAccount: data.LoginAccount,
		Password:     data.Password,
		Type:         data.Type,
		State:        "1",
		ParentId:     data.ParentId,
		ParentName:   data.ParentName,
		OperatorId:   data.OperatorId,
		CreatedAt:    time.Now().Unix(),
		UpdatedAt:    time.Now().Unix(),
		WithdrawFee:  data.WithdrawFee,
		RechargeFee:  data.RechargeFee,
		ApiFee:       data.ApiFee,
		GameFeeRate:  data.GameFeeRate,
	}
	InviteUrlConfig := GameConfigByType(2)
	record.InviteUrl = InviteUrlConfig.CfgValue + Id

	tx := meta.MerchantDB
	query, _, _ := dialect.Insert("tbl_business_info").Rows(record).ToSQL()

	_, err := tx.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return err
}

func BusinessUpdate(data TblBusinessInfo) error {
	if data.ParentId == "0" || data.ParentId == "" {
		data.Type = "业务组长"
	}
	if data.Type == "业务组长" {
		data.ParentId = "0"
		data.ParentName = ""
	}
	if data.Id == data.ParentId {
		return errors.New("不能挂靠自身")
	}
	//业务员不能挂靠自己和下级
	allRelation := GetBusinessTeam(data.Id, data.Id)
	allRelationArr := strings.Split(allRelation, ",")
	for _, value := range allRelationArr {
		if value == data.ParentId {
			return errors.New("不能挂靠下级")
		}
	}
	if ValidatePassword(data.Password) == false {
		return errors.New("业务员密码至少8位数，大、小写英文字母+数字组合")
	}

	record := g.Record{
		"parent_id":     data.ParentId,
		"parent_name":   data.ParentName,
		"account_name":  data.AccountName,
		"login_account": data.LoginAccount,
		"password":      data.Password,
		"type":          data.Type,
		"State":         data.State,
		"updated_at":    time.Now().Unix(),
		"recharge_fee":  data.RechargeFee,
		"withdraw_fee":  data.WithdrawFee,
		"game_fee_rate": data.GameFeeRate,
	}
	if data.Seamo == "unbind" {
		record["seamo"] = ""
	}
	query, _, _ := dialect.Update("tbl_business_info").Set(&record).Where(g.Ex{"id": data.Id}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func BusinessApifeeUpdate(adminName, adminId string, data TblBusinessInfo) error {

	record := g.Record{
		"api_fee":       data.ApiFee,
		"recharge_fee":  data.RechargeFee,
		"withdraw_fee":  data.WithdrawFee,
		"game_fee_rate": data.GameFeeRate,
		"updated_at":    time.Now().Unix(),
	}
	query, _, _ := dialect.Update("tbl_business_info").Set(&record).Where(g.Ex{"id": data.Id}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func GetBusinessInfoByUsername(username string) (TblBusinessInfo, error) {
	data := TblBusinessInfo{}
	t := dialect.From("tbl_business_info")
	query, _, _ := t.Select(colsBusinessInfo...).Where(g.Ex{"account_name": username}).Limit(1).ToSQL()

	err := meta.MerchantDB.Get(&data, query)
	if err != nil {
		return data, err
	}
	return data, nil
}

func GetBusinessInfoByLoginAccount(username string) (TblBusinessInfo, error) {
	data := TblBusinessInfo{}
	t := dialect.From("tbl_business_info")
	query, _, _ := t.Select(colsBusinessInfo...).Where(g.Ex{"login_account": username}).Limit(1).ToSQL()

	err := meta.MerchantDB.Get(&data, query)
	if err != nil {
		return data, err
	}
	return data, nil
}

func GetBusinessInfoById(id string) (TblBusinessInfo, error) {
	data := TblBusinessInfo{}
	t := dialect.From("tbl_business_info")
	query, _, _ := t.Select(colsBusinessInfo...).Where(g.Ex{"id": id}).Limit(1).ToSQL()

	err := meta.MerchantDB.Get(&data, query)
	// 账号不存在提示
	if err == sql.ErrNoRows {
		return data, errors.New(helper.UserNotExist)
	}
	return data, nil
}

func UpdateBusinessPassword(id string, password string, operator_id string) error {
	if ValidatePassword(password) == false {
		return errors.New("业务员密码至少8位数，大、小写英文字母+数字组合")
	}

	record := g.Record{
		"password": password,
	}
	where := g.Ex{}
	if id != "" {
		where["id"] = id
	}
	if operator_id != "" {
		where["operator_id"] = operator_id
	}
	query, _, _ := dialect.Update("tbl_business_info").Set(record).Where(where).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		body := fmt.Errorf("%s,[%s]", err.Error(), query)
		return pushLog(body, "数据库错误")
	}
	return nil
}

func UpdateBusinessState(id string, state int) error {
	record := g.Record{
		"state": state,
	}
	query, _, _ := dialect.Update("tbl_business_info").Set(record).Where(g.Ex{"id": id}).ToSQL()
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		body := fmt.Errorf("%s,[%s]", err.Error(), query)
		return pushLog(body, "数据库错误")
	}
	return nil
}

type BusinessInfo struct {
	Id          int    `db:"id" json:"id"`
	AccountName string `db:"account_name" json:"account_name"`
}

func GetBusiness(id int) ([]BusinessInfo, error) {

	data := []BusinessInfo{}
	where := " "
	if id > 0 {
		where = " where id<>" + strconv.Itoa(id)
	}
	query := "select id,account_name from tbl_business_info " + where
	err := meta.MerchantDB.Select(&data, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

func GetBusinessMap() (map[string]string, error) {
	data := map[string]string{}
	list, _ := GetBusiness(0)
	for _, val := range list {
		data[strconv.Itoa(val.Id)] = val.AccountName
	}
	return data, nil
}

func UpdateBusinessGoogleSecret(id string, seamo string) error {
	record := g.Record{
		"seamo": seamo,
	}
	query, _, _ := dialect.Update("tbl_business_info").Set(record).Where(g.Ex{"id": id}).ToSQL()
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		body := fmt.Errorf("%s,[%s]", err.Error(), query)
		return pushLog(body, "数据库错误")
	}
	return nil
}
